package game.fury;

import java.util.ArrayList;

import game.components.Balls;
import game.components.Brick;
import game.components.Collision;
import game.components.Component;
import game.components.Constants;
import game.components.Padle;
import game.components.PowerUp;
import game.components.Score;
import game.components.Update;
import android.graphics.Canvas;
import android.view.MotionEvent;
import sheep.collision.CollisionLayer;
import sheep.collision.CollisionListener;
import sheep.game.Game;
import sheep.game.Sprite;
import sheep.game.State;
import sheep.gui.TextButton;
import sheep.gui.WidgetAction;
import sheep.gui.WidgetListener;
//import sheep.graphics.Image;
import sheep.input.TouchListener;
import sheep.math.Vector2;


/**
 * This is the game screen that sets up all of the game components and call the update and draw methods
 * @author Marius Haugen
 */


public class FuryScreen extends State implements TouchListener, CollisionListener, WidgetListener {
	
	public Padle padle;
	protected Sprite backgroudSprite;
	protected Sprite playLine;
	protected Sprite topBackground;
	protected Sprite scoreLine;
	protected Sprite leftSide;
	protected Sprite rightSide;
	protected Sprite topSide;
	
	public Constants con;
	
	private int type;
	
	public CollisionLayer colLayer;
	
	public ArrayList<Brick> bricks;
	public ArrayList<Balls> balls;
	public ArrayList<PowerUp> powerUps;
	
	public ArrayList<Vector2> currentBallSpeed;
 	

	public Score stats;


	public boolean gameOver;
	public boolean gameWon;
	protected boolean firstTouch;
	protected boolean isRunning;
	protected TextButton pauseButton;

	/**
	 * Constructor for the game screen. 
	 * 
	 * @param game The game object
	 * @param type Sets type of level that is created
	 * @param score The score from previous levels
	 */
	public FuryScreen(Game game, int type, int score){
		
		this.type = type;
		
		LoadGame.loadGame(this, score);
		
		addTouchListener(pauseButton);
		pauseButton.addWidgetListener(this);

		this.addTouchListener(new TouchListener() {

			@Override
			public boolean onTouchDown(MotionEvent event) {
				if(gameOver){
					pushIntro();
				}
				else if(gameWon){
					pushNextLevel();
				}
				else if(!firstTouch){
					firstTouch = true;
					startBalls();
				}
				return false;
			}

			@Override
			public boolean onTouchUp(MotionEvent event) {
				return false;
			}

			@Override
			public boolean onTouchMove(MotionEvent event) {
				if(playLine.getBoundingBox().contains(event.getX(),event.getY())){
					if(isRunning) {
						Update.movePadle(event.getX(), padle);
					}
				}
				return false;
			}
			
		});
	 	
	}


	/**
	 * Draws the objects of the game on the screen. 
	 * Displays "Game over" and "Game won" texst, plus the scores  at the end of the game
	 */
	public void draw(Canvas canvas){
		
		backgroudSprite.draw(canvas);
		scoreLine.draw(canvas);
		playLine.draw(canvas);
		colLayer.draw(canvas, null);
		pauseButton.draw(canvas);

		
		canvas.drawText("Score: "+ Score.getLevelScore()+" Balls: "+Score.getBalls(), 10, 25, con.paintScore);
		
		if(gameOver){
			canvas.drawText("Game over", 110, 400, con.paintGameOver);
		}
		
		if(gameWon){
			pauseGame();
					
			if(type < con.maxLevel){
				canvas.drawText("Level clear!", 70, 400, con.paintGameOver);
				canvas.drawText("Level score is: "+Score.getLevelScore(), 70, 450, con.paintGameOver);
				canvas.drawText("Total score is: "+Score.getTotalScore(), 70, 500, con.paintGameOver);
			}
			else{
				canvas.drawText("Game won!", 70, 400, con.paintGameOver);
				canvas.drawText("Level score is: "+Score.getLevelScore(), 70, 450, con.paintGameOver);
				canvas.drawText("Total score is: "+Score.getTotalScore(), 70, 500, con.paintGameOver);
			}
		}
	}
	
	public void update(float dt){
		//checks if any of the balls has hit the wall, or gone out of the play field, and updates balls and poweups
		Update.updateFuryScreen(this, dt);
		
		colLayer.update(dt);
		playLine.update(dt);
		scoreLine.update(dt);
		

	}
	

	/**
	 * Pushes the introScreen
	 */
	public void pushIntro(){
		this.getGame().popState();
	}
	/**
	 * Pushes the next level, or the introScreen if this is the last level
	 */
	public void pushNextLevel(){
		// pop current level
		this.getGame().popState();
		
		//Push next level
		if(type != 0 & type <con.maxLevel){
			type++;
			getGame().pushState(new FuryScreen(getGame(), type, Score.getTotalScore()));
		}
		
		//else go back to IntroScreen
	}

	/**
	 * Pauses balls and powerUps
	 */
	public void pauseGame(){
		isRunning = false;
		Update.pauseGame(this);
	}
	
	
	/**
	 * Starts the balls at the beginning for the game
	 */
	private void startBalls() {
		Update.startBalls(this);
	}
	
	public void setPadle(Padle padle) {
		this.padle = padle;
	}


	public int getType() {
		return type;
	}


	public void setType(int type) {
		this.type = type;
	}
	
	/**
	 * Adds a component to the CollisionLayer and adds listeners
	 * @param com The component being added
	 */
	public void addToColLayer(Component com){
		colLayer.addSprite(com);
		com.addCollisionListener(com);
		com.addCollisionListener(this);
	}
	
	/**
	 * Removes a component from the CollisionLayer and removes listeners
	 * @param com The component being added
	 */
	public void removeFromColLayer(Component com){
		colLayer.removeSprite(com);
		com.removeCollisionListener(com);
		com.removeCollisionListener(this);
	}

	@Override
	public void collided(Sprite a, Sprite b) {
		if(a instanceof PowerUp & b instanceof Padle){
			Collision.padlePowerUpCollision((PowerUp)a, this);
		}
		if(a instanceof Balls & b instanceof Brick){
			Collision.brickCollision((Balls)a,(Brick) b, this);
		}
		if(a instanceof Balls & b instanceof Padle){
			Collision.padelBallCollision((Padle) b, (Balls) a, con);
		}
	
	}



	@Override
	public void actionPerformed(WidgetAction action) {
		if(action.getSource().equals(pauseButton)){
			getGame().pushState(new PauseScreen());
		}
	
		
	}


}
